package com.ZeroCarbon.service;

import com.ZeroCarbon.exception.BusinessLogicException;
import com.ZeroCarbon.utils.JwtTool;
import com.ZeroCarbon.utils.UserHolder;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;

import static com.ZeroCarbon.prefix.RedisKey.LOGIN;

/**
 * Token处理层
 *
 * @since 2025-7-20
 */
@Component
@RequiredArgsConstructor
public class TokenService {

    private final JwtTool jwtTool;

    private final StringRedisTemplate redis;


    /**
     * 更新Access Token（只有在Access Token过期或双Token都过期才会用）
     *
     * @return Access Token
     */
    public String updateAccessToken(HttpServletRequest request, HttpServletResponse response) {
        // 获取Refresh Token
        String refreshToken = request.getHeader("Refresh-Token");
        // 获取用户id
        String userId = UserHolder.getUser();
        // 如果用户id为空，则说明没登录
        if (userId == null) {
            return null;
        }
        // 重新生成Access Token
        String newAccessToken = jwtTool.generateAccessToken(userId, request, Duration.ofMinutes(30));
        try {
            // 校验Refresh Token
            jwtTool.parseRefreshToken(refreshToken, request);
        } catch (BusinessLogicException e) {
            // 获取过期信息
            String message = e.getMessage();
            // Refresh Token过期的情况
            if (message.equals(BusinessLogicException.EXPIRED_EXCEPTION)) {
                // 设置402状态码，Refresh Token过期无法无感刷新，需要重新登录
                response.setStatus(402);
                // 返回数据null
                return null;
            }
        }
        // 重新设置Redis相关key为登录状态
        redis.opsForValue().set(LOGIN + userId, "1");
        // 如果Refresh Token没有过期则直接返回Access Token
        return newAccessToken;
    }
}
